package engine.display.newAttack
{
	import engine.control.Base64;
	import engine.display.TalkManage;
	import engine.display.newAttack.action.AreaAttack;
	import engine.display.newAttack.action.ManyPhyCloseAttack;
	import engine.display.newAttack.action.SinglePhyCloseAttack;
	import engine.display.newAttack.vo.AttackActionVo;
	import engine.display.newAttack.vo.AttackVo;
	import engine.display.newAttack.vo.BoutInfo;
	import engine.display.newAttack.vo.BoutVo;
	import engine.display.newAttack.vo.DamageVo;
	import engine.display.newAttack.vo.FlowVo;
	import engine.net.messages.CustomToServerFlag;
	import engine.net.mgr.SystemSender;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.utils.setTimeout;
	
	import newx.com.config.StaticIni;
	import newx.utils.debug.IO;

	public class FightLogic extends EventDispatcher
	{
		public static const FIGHT_OVER : String = "fight_over";
		
		private var _flowVos		:	Vector.<FlowVo>;
		
		private var _attackVo		:	AttackVo;
		
		private var _attackView	:	AttackSceneView;
		
		private var _attackSkillNameEffect : AttackSkillNameLogic;
		
		public function FightLogic( attackView : AttackSceneView ):void
		{
			_attackView = attackView;
			
			_attackSkillNameEffect = AttackSkillNameLogic.getInstance();
			
			_attackSkillNameEffect.setPlace( attackView.topEffectSpace );
		}
		
		public function startFight( attackVo : AttackVo ):void
		{
//			try
//			{
				_attackVo = attackVo;
				addPetFight();
				startBout();				
//			}catch(e:Error)
//			{
//				var attackReport:String = 	AttackLogic.getInstance()._catchAttackStr;
//				SystemSender.getInstance().CustomMsg( CustomToServerFlag.CLIENT_CUSTOMMSG_ERROR_REPORT,attackReport );
//				IO.traceLog("战报出错了。");
//				IO.traceLog(Base64.UnCompress(attackReport));
//				fightOver();
//			}
		}
		
		/**
		 *获取第一个攻击对象 1左边  －1 右边
		 * 
		 */
		private function getFristAttackPlayer():int
		{
			var boutVo:BoutVo = _attackVo.boutVos[0] as BoutVo;
			var flow:FlowVo = boutVo.flowVos[0];
			if(flow.attackPos<9)
			{
				return 1;	
			}else
			{
				return -1;	
			}
		}
		
		/**
		 * 
		 * 添加宠物开头动画
		 * 
		 */
		public function addPetFight():void
		{
			var leftArr:Array = AttackLogic.getInstance().attackScene.getAttackPlayerFromPosArr([0,1,2,3,4,5,6,7,8,9]);
			var rightArr:Array = AttackLogic.getInstance().attackScene.getAttackPlayerFromPosArr([10,11,12,13,14,15,16,17,18]);
			var boutVo:BoutVo = _attackVo.boutVos[0] as BoutVo;
			var boutInfo:BoutInfo = boutVo.boutInfoVos[0];
			
			var leftPet:AttackPet = AttackLogic.getInstance().attackScene.leftPet;
			var rightPet:AttackPet = AttackLogic.getInstance().attackScene.rightPet;
			
			var i:int = 0;
			var attackplay:AttackPlayer;
			var frist:int = getFristAttackPlayer();
			var flow:FlowVo = new FlowVo(19,0,StaticIni.getIniVar("attackPetSkill","skill"),0,0,0,"",null,"");
			var flow1:FlowVo = new FlowVo(20,0,StaticIni.getIniVar("attackPetSkill","skill"),0,0,0,"",null,"");
			if(frist == 1)
			{//左边
				boutVo.flowVos.unshift(flow1)
				boutVo.flowVos.unshift(flow)
			}else
			{
				boutVo.flowVos.unshift(flow)
				boutVo.flowVos.unshift(flow1)
			}
			
			if(leftPet._fightInfoVo)
			{
				for( i = 0;i < leftArr.length;i++)
				{
					attackplay = leftArr[i] as AttackPlayer;
					if(!attackplay) continue;
					if(!attackplay.fightInfoVo) continue;
					var damageVo:DamageVo = new DamageVo(0,0,0,attackplay.fightInfoVo.hp,attackplay.fightInfoVo.mp,attackplay.pos,0,"82000014:1:1:",attackplay.fightInfoVo.maxHp,0);
					flow.damageVos.push(damageVo)
				}
			}
			
			if(rightPet._fightInfoVo)
			{
				for( i = 0;i < rightArr.length;i++)
				{
					attackplay = rightArr[i] as AttackPlayer;
					if(!attackplay) continue;
					if(!attackplay.fightInfoVo) continue;
					var damageVo1:DamageVo = new DamageVo(0,0,0,attackplay.fightInfoVo.hp,attackplay.fightInfoVo.mp,attackplay.pos,0,"82000014:1:1:",attackplay.fightInfoVo.maxHp,0);
					flow1.damageVos.push(damageVo1)
				}
			}
		}
		
		/**
		 *	战斗结束 
		 */		
		public function fightOver():void
		{
			dispatchEvent( new Event( FIGHT_OVER ) );
		}
		
		private function fightControl():void
		{
			if( 0 >= _flowVos.length )
			{
				//说明要新回合了
				if( 0 == _attackVo.boutVos.length )
				{//战斗结束
					fightOver();
				}else
				{
					startBout();
				}
			}else
			{
				//看下是否吹牛逼
				if( !npcSpeak() )
				{
					startFlow();
				}
			}
		}
		
		private function npcSpeak():Boolean
		{
			var flow :FlowVo =	_flowVos[ 0 ];
			
			if( flow.speak != "" )
			{
				var player : AttackPlayer = _attackView.getAttackPlayerFromPos( flow.attackPos );
				player.speak( flow.speak.split(";")[ 0 ]);
				setTimeout( function():void
				{
					player.speak( "" );
					startFlow();
				}, flow.speak.split(";")[ 1 ] * 1000 );
				
				return true;
			}else
			{
				return false;
			}
		}
		
		/**
		 *	开始回合 
		 */
		private function startBout():void
		{
			//清空特效
			_attackView.freeEffectSpace();
			
			var boutVo : BoutVo = _attackVo.boutVos.shift();
			
//			//播放回合动画
//			_attackView.topEffectSpace.addChild(_boutEffect);
//			_boutEffect.gotoAndPlay(1);	
//			_boutEffect["movie"].gotoAndPlay(1);
//			_boutEffect["text"]		=	"第 " + boutVo.count + " 回合";

			_flowVos = boutVo.flowVos;
			
			resetPlayerInfo( boutVo.boutInfoVos );
			
			onMovePlayer();
			
			fightControl();
		}
		
		/**
		 *	初始化玩家基本信息（hp，mp） 
		 * 
		 */		
		private function resetPlayerInfo( boutInfos : Vector.<BoutInfo> ):void
		{
			var player : AttackPlayer;
			
			for each( var boutInfo : BoutInfo in boutInfos )
			{
				player = _attackView.getAttackPlayerFromPos( boutInfo.pos );
				
				if( null != player && player.visible )
				{
					player.resetHp( boutInfo.hp, boutInfo.maxhp );
					player.resetMp( boutInfo.mp );
					player.showBuffer( boutInfo.buffer );
				}
			}
		}
		
		/**
		 *	是否反击回合 
		 * @return 
		 * 
		 */		
		private function isCounterattack( flow : FlowVo, attackActionVo : AttackActionVo ):Boolean
		{
//			8100006	反击技能
			if( _flowVos[ 0 ].skill == "81000006"  && 
				( attackActionVo.flag == "00000" ) )
			{//是反击技能 && 2个人在一个位置&&近战攻击
				return true
			}
			return false;
		}
		
		private function initCounterattackData( flow : FlowVo, attackActionVo : AttackActionVo ):void
		{
			if( _flowVos.length > 0 && isCounterattack( flow, attackActionVo ) )
			{
				var counterattackFlow : FlowVo = _flowVos.shift();
				
				var damageVo : DamageVo = counterattackFlow.damageVos[ 0 ]
				damageVo.counterattack = true;
				flow.damageVos.push( damageVo );
				
				initCounterattackData( flow, attackActionVo );
			}
		}
		
		/**
		 *	开始回合中流程 
		 */		
		private function startFlow():void
		{
			var flow 		:FlowVo 		=	_flowVos.shift();
			
			if( flow.damageVos.length == 0 )
			{
				fightControl();
				return;
			}
			
			var attackActionVo : AttackActionVo = new AttackActionVo( flow );
			
			initCounterattackData( flow, attackActionVo );
			
			//施法者
			var fPlayer		:AttackPlayer	=	_attackView.getAttackPlayerFromPos( flow.attackPos );
			//目标者
			var tPlayers	:Array			=	[ _attackView.getAttackPlayerFromPos( flow.targetPos ) ];
			
			for( var i : int= 0; i < flow.damageVos.length; i++ )
			{
				tPlayers.push( _attackView.getAttackPlayerFromPos( flow.damageVos[ i ].pos ) );
			}
			
			function showSkillEffect( fPlayer : AttackPlayer ):void
			{
				_attackSkillNameEffect.playSkillName( attackActionVo.skill );
				if(!(fPlayer is AttackPet))
				{
					fPlayer.resetMp( 0 );
				}
			}
			
			if( attackActionVo.skillAttackType == 5 )
			{//技能攻击
				showSkillEffect( fPlayer );
			}
			
			switch( attackActionVo.flag )
			{
				case "10000":
					//					多人 近战 物理-
					new ManyPhyCloseAttack(fPlayer,
						tPlayers,
						flow,
						attackActionVo,
						onMovePlayer,
						fightControl).play();
					break;
				case "00000":
					//单人 近战 物理
					new SinglePhyCloseAttack(fPlayer,
						tPlayers,
						flow,
						attackActionVo,
						onMovePlayer,
						fightControl).play();
					break;
				case "00100":
				case "10100":
					//单人/多人 远程 物理
					new AreaAttack(fPlayer,
						tPlayers,
						flow,
						attackActionVo,
						_attackView.topEffectSpace,
						fightControl).play(attackActionVo.skillAttackType,"Attack");//attackActionVo.skillAttackType
					break;
				default:
				{
					new AreaAttack(fPlayer,
						tPlayers,
						flow,
						attackActionVo,
						_attackView.topEffectSpace,
						fightControl).play(attackActionVo.skillAttackType,"Attack");//attackActionVo.skillAttackType
					break;
				}
			}
		}
		
		/**
		 *	强制结束战斗 ( 一件结束战斗 )
		 */		
		public function killFight():void
		{
			if( null != _attackVo )
			{
				_attackVo.boutVos = new Vector.<BoutVo>();
				
				_flowVos = new Vector.<FlowVo>();
			}
		}
		
		private function onMovePlayer():void
		{
			_attackView.onUpdateAttackDepth();
		}
	}
}